﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;

namespace SwormTests.Types
{
    public class supported_types : TestBase
    {
        public supported_types(DbToTest type) : base(type) { }

        static long TickDelta = TimeSpan.FromSeconds(1).Ticks;

        public class type_test
        {
            [Sworm.Column(IsPrimaryKey = true, IsAutoIncrement = false)]
            public long id { get; set; }

            public int int1 { get; set; }
            public int? int2 { get; set; }
            public long long1 { get; set; }
            public long? long2 { get; set; }
            public string string1 { get; set; }
            public bool bool1 { get; set; }
            public bool? bool2 { get; set; }
            public decimal decimal1 { get; set; }
            public decimal? decimal2 { get; set; }
            public double double1 { get; set; }
            public double? double2 { get; set; }
            public float float1 { get; set; }
            public float? float2 { get; set; }
            public Guid guid1 { get; set; }
            public Guid? guid2 { get; set; }
            public DateTime datetime1 { get; set; }
            public DateTime? datetime2 { get; set; }
            public byte[] binary1 { get; set; }

            // can we do anything with these?
            //public DateTimeOffset datetimeoffset1 { get; set; }
            //public DateTimeOffset? datetimeoffset2 { get; set; }
        }

        [Test]
        public void test_all_columns()
        {
            var record = new type_test();
            record.id = 1;
            record.int1 = 2;
            record.int2 = 3;
            record.long1 = 4;
            record.long2 = 5;
            record.string1 = "6";
            record.bool1 = true;
            record.bool2 = true;
            record.decimal1 = 7.7m;
            record.decimal2 = 8.8m;
            record.double1 = 9.9;
            record.double2 = 10.10;
            record.float1 = 11.11f;
            record.float2 = 12.12f;
            record.guid1 = Guid.NewGuid();
            record.guid2 = Guid.NewGuid();
            record.datetime1 = DateTime.Now;
            record.datetime2 = DateTime.Now.AddHours(-1);
            record.binary1 = ASCIIEncoding.Default.GetBytes("binary1");

            DB.Insert(record);
            var item = DB.Query.Joining<type_test>("x").List().Single();

            Assert.AreEqual(1, item.id);
            Assert.AreEqual(2, item.int1);
            Assert.AreEqual(3, item.int2);
            Assert.AreEqual(4, item.long1);
            Assert.AreEqual(5, item.long2);
            Assert.AreEqual("6", item.string1);
            Assert.AreEqual(true, item.bool1);
            Assert.AreEqual(true, item.bool2);
            Assert.AreEqual(7.7, (double)(item.decimal1), 0.001);
            Assert.AreEqual(8.8, (double)(item.decimal2), 0.001);
            Assert.AreEqual(9.9, item.double1, 0.001);
            Assert.AreEqual(10.10, item.double2, 0.001);
            Assert.AreEqual(11.11d, (double)item.float1, 0.001);
            Assert.AreEqual(12.12d, (double)item.float2, 0.001);
            Assert.AreEqual(record.guid1, item.guid1);
            Assert.AreEqual(record.guid2, item.guid2);
            Assert.AreEqual(record.datetime1.Ticks, item.datetime1.Ticks, TickDelta);
            Assert.AreEqual(record.datetime2.Value.Ticks, item.datetime2.Value.Ticks, TickDelta);
            Assert.AreEqual("binary1", ASCIIEncoding.Default.GetString(item.binary1));
        }

        [Test]
        public void test_nullability()
        {
            var record = new type_test();
            record.id = 1;

            DB.Insert(record);
            var item = DB.Query.Joining<type_test>("x").List().Single();

            Assert.AreEqual(1, item.id);
            Assert.AreEqual(0, item.int1);
            Assert.AreEqual(null, item.int2);
            Assert.AreEqual(0, item.long1);
            Assert.AreEqual(null, item.long2);
            Assert.AreEqual(null, item.string1);
            Assert.AreEqual(false, item.bool1);
            Assert.AreEqual(null, item.bool2);
            Assert.AreEqual(0.0, (double)(item.decimal1), 0.001);
            Assert.AreEqual(null, item.decimal2);
            Assert.AreEqual(0.0, item.double1, 0.001);
            Assert.AreEqual(null, item.double2);
            Assert.AreEqual(0.0, (double)item.float1, 0.001);
            Assert.AreEqual(null, item.float2);
            Assert.AreEqual(Guid.Empty, item.guid1);
            Assert.AreEqual(null, item.guid2);
            Assert.AreEqual(record.datetime1.Ticks, item.datetime1.Ticks, TickDelta);
            Assert.AreEqual(null, item.datetime2);
            Assert.AreEqual(null, item.binary1);
        }
    }
}
